package com.yunhe.option.service.data.impl;

import com.yunhe.option.domain.data.SeasonPrice;
import com.yunhe.option.domain.data.SeasonPriceDetail;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.exception.ObjectNotFoundException;
import com.yunhe.common.exception.UniqueConstraintsException;
import com.yunhe.option.repository.data.SeasonPriceDetailRepository;
import com.yunhe.option.service.data.SeasonPriceDetailService;
import com.yunhe.option.service.data.SeasonPriceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 季节电价详情服务类实现
 */
@Service
public class SeasonPriceDetailServiceImpl implements SeasonPriceDetailService {
    @Autowired
    private SeasonPriceDetailRepository seasonPriceDetailRepository;
    @Autowired
    private SeasonPriceService seasonPriceService;

    private void processBeforeSave(SeasonPriceDetail seasonPriceDetail)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException{
        if (seasonPriceDetail.getStartTime() == null
                || seasonPriceDetail.getEndTime() == null
                || seasonPriceDetail.getPrice() == null) {
            throw new ArgumentErrorException("参数不能为空");
        }
    }

    /**
     * 新增季节电价详情对象
     * @param seasonPriceDetail
     * @param seasonPriceId
     * @return
     * @throws ArgumentErrorException
     * @throws UniqueConstraintsException
     * @throws ObjectNotFoundException
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    @Override
    public SeasonPriceDetail create(SeasonPriceDetail seasonPriceDetail, Long seasonPriceId)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException {
        seasonPriceDetail.setId(null);
        processBeforeSave(seasonPriceDetail);
        SeasonPriceDetail newDetail = seasonPriceDetailRepository.save(seasonPriceDetail);
        seasonPriceDetailRepository.bindSeasonPrice(newDetail.getId(), seasonPriceId);
        seasonPriceDetailRepository.bindPriceRate(newDetail.getId(), newDetail.getPriceRateCode());
        return newDetail;
    }

    /**
     * 批量新增季节电价详情
     * @param details
     * @param seasonPriceId
     * @return
     * @throws ArgumentErrorException
     * @throws UniqueConstraintsException
     * @throws ObjectNotFoundException
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    @Override
    public Iterable<SeasonPriceDetail> create(List<SeasonPriceDetail> details, Long seasonPriceId) throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException {
        Iterable<SeasonPriceDetail> newSeasonPriceDetail = seasonPriceDetailRepository.saveAll(details);
        for(SeasonPriceDetail seasonPriceDetail : newSeasonPriceDetail) {
            processBeforeSave(seasonPriceDetail);
            this.create(seasonPriceDetail, seasonPriceId);
        }
        return  newSeasonPriceDetail;
    }

    /**
     * 根据ID删除季节电价详情
     * @param seasonPriceDetailId
     * @throws ObjectNotFoundException
     * @throws UniqueConstraintsException
     * @throws ArgumentErrorException
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    @Override
    public void delete(Long seasonPriceDetailId)
            throws ObjectNotFoundException, UniqueConstraintsException, ArgumentErrorException {
        seasonPriceDetailRepository.deleteById(seasonPriceDetailId);
        SeasonPrice seasonPrice = seasonPriceDetailRepository.findSeasonPriceByDetailId(seasonPriceDetailId);
        if (seasonPrice != null) {
            seasonPriceService.update(seasonPrice);
        }
    }

    /**
     * 更新季节电价详情（全部字段）
     * @param seasonPriceDetail
     * @return
     * @throws ArgumentErrorException
     * @throws UniqueConstraintsException
     * @throws ObjectNotFoundException
     */
    @Override
    public SeasonPriceDetail update(SeasonPriceDetail seasonPriceDetail) throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException {
        boolean exists = seasonPriceDetail.getId() != null && seasonPriceDetailRepository.existsById(seasonPriceDetail.getId());
        if (!exists) {
            throw new ObjectNotFoundException("找不到ID为" + seasonPriceDetail.getId() + "的季节电价详情");
        }
        processBeforeSave(seasonPriceDetail);
        return seasonPriceDetailRepository.save(seasonPriceDetail);
    }

    /**
     * 更新季节电价详情（指定字段）
     * @param seasonPriceId
     * @param seasonPriceDetailId
     * @param price
     * @param startTime
     * @param endTime
     * @return
     * @throws ArgumentErrorException
     * @throws ObjectNotFoundException
     * @throws UniqueConstraintsException
     */
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    @Override
    public SeasonPriceDetail update(Long seasonPriceId,
                                    Long seasonPriceDetailId,
                                    Double price,
                                    Date startTime,
                                    Date endTime)
            throws ArgumentErrorException, ObjectNotFoundException, UniqueConstraintsException {
        SeasonPriceDetail seasonPriceDetail = this.findById(seasonPriceDetailId).get();
        if (seasonPriceDetail == null) {
            throw new ObjectNotFoundException("找不到ID为" + seasonPriceDetail.getId() + "的季节电价详情");
        }
        Optional.ofNullable(startTime).ifPresent(seasonPriceDetail::setStartTime);
        Optional.ofNullable(endTime).ifPresent(seasonPriceDetail::setEndTime);
        if (price != null) {
            Long priceRateCode = seasonPriceDetail.getPriceRateCode();
            seasonPriceDetailRepository.updateAllPrice(seasonPriceId, priceRateCode, price);
        }
        return seasonPriceDetailRepository.save(seasonPriceDetail);
    }

    /**
     * 根据条件查找季节电价详情
     * @param seasonPriceId
     * @param priceRateCode
     * @return
     */
    @Override
    public Iterable<SeasonPriceDetail> search(Long seasonPriceId,
                                              Long priceRateCode) {
        if (seasonPriceId != null && priceRateCode != null) {
            Iterable<SeasonPriceDetail> results =
                    seasonPriceDetailRepository.findBySeasonPriceIDAndPriceRateCode(seasonPriceId, priceRateCode);
            return results;
        } else if (seasonPriceId != null) {
            Iterable<SeasonPriceDetail> results = seasonPriceDetailRepository.findBySeasonPriceID(seasonPriceId);
            return results;
        }
        return null;
    }

    /**
     * 根据ID查找季节电价详情
     * @param id
     * @return
     */
    @Override
    public Optional<SeasonPriceDetail> findById(Long id) {
        return seasonPriceDetailRepository.findById(id);
    }

    /**
     * 根据季节电价ID和电价费率CODE删除季节电价详情
     * @param seasonPriceId
     * @param priceRateCode
     * @throws ArgumentErrorException
     */
    @Override
    public void deleteBySeasonPriceIdAndPriceRateCode(Long seasonPriceId, Long priceRateCode)
            throws ArgumentErrorException {
        seasonPriceDetailRepository.deleteBySeasonPriceIdAndPriceRateCode(seasonPriceId, priceRateCode);
    }
}
